﻿using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.Routing;
using System;
using System.Linq;
using Urs.Core;
using Urs.Core.Data;
using Urs.Data.Domain;
using Urs.Data.Domain.Users;
using Urs.Core.Infrastructure;
using Urs.Data.Domain.Configuration;
using Urs.Services.Users;
using Urs.Services.Security;

namespace Urs.Framework
{
    public class StoreClosedAttribute : TypeFilterAttribute
    {
        #region Fields

        private readonly bool _ignoreFilter;

        #endregion

        #region Ctor

        /// <summary>
        /// Create instance of the filter attribute
        /// </summary>
        /// <param name="ignore">Whether to ignore the execution of filter actions</param>
        public StoreClosedAttribute(bool ignore = false) : base(typeof(StoreClosedFilter))
        {
            this._ignoreFilter = ignore;
            this.Arguments = new object[] { ignore };
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets a value indicating whether to ignore the execution of filter actions
        /// </summary>
        public bool IgnoreFilter => _ignoreFilter;

        #endregion


        private class StoreClosedFilter : IActionFilter
        {
            #region Fields

            private readonly bool _ignoreFilter;
            private readonly IPermissionService _permissionService;
            private readonly StoreInformationSettings _storeInformationSettings;

            #endregion

            #region Ctor

            public StoreClosedFilter(bool ignoreFilter,
                IPermissionService permissionService,
                StoreInformationSettings storeInformationSettings)
            {
                this._ignoreFilter = ignoreFilter;
                this._permissionService = permissionService;
                this._storeInformationSettings = storeInformationSettings;
            }

            public void OnActionExecuted(ActionExecutedContext context)
            {
            }

            #endregion

            public void OnActionExecuting(ActionExecutingContext filterContext)
            {
                if (filterContext == null || filterContext.HttpContext == null)
                    return;

                //check whether this filter has been overridden for the Action
                var actionFilter = filterContext.ActionDescriptor.FilterDescriptors
                    .Where(filterDescriptor => filterDescriptor.Scope == FilterScope.Action)
                    .Select(filterDescriptor => filterDescriptor.Filter).OfType<StoreClosedAttribute>().FirstOrDefault();

                //ignore filter (the action is available even if a store is closed)
                if (actionFilter?.IgnoreFilter ?? _ignoreFilter)
                    return;

                if (!DataSettingsManager.DatabaseIsInstalled)
                    return;
                
                if (!_storeInformationSettings.StoreClosed)
                    return;

                var storeClosedUrl = new UrlHelper(filterContext).RouteUrl("StoreClosed");
                filterContext.Result = new RedirectResult(storeClosedUrl);
            }
        }
    }
}
